<template>
  <div class="upload">
    <el-upload
      v-model:file-list="fileList"
      action="https://xinmanrui.com/eduWebSiteApi/file/upload"
      :list-type="listType"
      :limit="limit"
      :on-preview="handlePreview"
      :on-remove="handleRemove"
      :before-upload="beforeAvatarUpload"
      :on-success="handleSuccess"
      :on-error="handleError"
      :class="{ hideAdd: fileList.length >= limit }"
    >
      <el-icon>
        <Plus />
      </el-icon>
    </el-upload>
    <el-image-viewer
      v-if="imgView"
      :url-list="urlList"
      :initial-index="initialIndex"
      hide-on-click-modal
      @close="imgViewClose"
    />
    <div v-if="tips" class="tips">{{ tips }}</div>
  </div>
</template>

<script setup>
import DOCX from "@/assets/docx.png";
import FILE from "@/assets/file.png";
import PDF from "@/assets/pdf.png";
import PPTX from "@/assets/pptx.png";
import VIDEO from "@/assets/video.png";
import XLSX from "@/assets/xlsx.png";
import ZIP from "@/assets/ZIP.png";
import { Plus } from "@element-plus/icons-vue";
import { ElMessage } from "element-plus";
import { ref, watch } from "vue";

defineOptions({
  name: "FileUpload"
});

// 传值
const props = defineProps({
  modelValue: {
    type: String,
    default: ""
  },
  listType: {
    type: String,
    default: "picture-card"
  },
  limit: {
    type: Number, //允许上传文件的最大数量
    default: 1
  },
  disabled: {
    type: Boolean,
    default: false
  },
  multiple: {
    //是否支持多选文件
    type: Boolean,
    default: false
  },
  fileType: {
    type: Array,
    default() {
      return ["doc", "docx", "xls", "xlsx", "pdf", "png", "jpg", "pptx"];
    }
  },
  maxSize: {
    //允许上传的文件大小 0 ~ 20(单位M)
    type: Number,
    default: 2
  },
  tips: {
    type: String,
    default: ""
  }
});
const emit = defineEmits(["update:modelValue"]);

const isInit = ref(false);
const fileList = ref([]);
const fileSuccess = ref([]);
const fileTypes = ref("");
// const filePreUrl = localStorage.getItem("picurl");
const filePreUrl = "https://xinmanrui.com/eduWebSiteApi";

const fileUrlObj = {
  pdf: PDF,
  xlsx: XLSX,
  doc: DOCX,
  docx: DOCX,
  zip: ZIP,
  txt: FILE,
  mp4: VIDEO,
  pptx: PPTX
};

// 文件上传之前
const beforeAvatarUpload = file => {
  fileTypes.value = file.name.match(/\.[^.]+$/g)[0].replace(/\./g, "");
  // console.log(file)
  // 允许上传的文件格式props.fileType = ['jpg','jpeg','png','pdf','zip', ...]
  if (
    props.fileType.length &&
    !props.fileType.includes(file.name.match(/\.[^.]+$/g)[0].replace(/\./g, ""))
  ) {
    ElMessage({
      message: `允许上传的格式: ${props.fileType.join(" | ")}`,
      type: "warning"
    });
    return false;
  }
  // 允许上传的文件大小 file.size单位是字节 转换(file.size / 1024) kb,转换(file.size/1024/1024)M
  // console.log(file.size) 小于等于 20M  (props.maxSize 单位是M)
  if (file.size / 1024 / 1024 >= props.maxSize) {
    ElMessage({
      message: `允许上传的文件大小 0 ~ ${props.maxSize} M`,
      type: "warning"
    });
    return false;
  }
};

// 上传成功
// console.log(getImgUrl('icon/pdf.svg'))
const handleSuccess = (response, uploadFile, uploadFiles) => {
  if (response.code !== 200) {
    ElMessage.error(response.msg);
    return false;
  } else {
    // 设置文件封面
    let suffix = uploadFile.name.split(".").pop().toLowerCase();
    if (fileUrlObj[suffix]) {
      let fileData = fileList.value.find(v => v.uid == uploadFile.uid);
      fileData.url = fileUrlObj[suffix];
    }

    // 设置值
    let fileData = {
      name: uploadFile.name,
      fileUrl: response.data,
      suffix: suffix,
      source: 1 // 来源 1:pc
    };
    fileSuccess.value.push(fileData);
    setMadelVal();
  }
};

const handleError = (error, uploadFile, uploadFiles) => {
  // console.log('error', error)
  // console.log('uploadFile', uploadFile)
  // console.log('uploadFiles', uploadFiles)
};

//删除
const handleRemove = (file, uploadFiles) => {
  const fileUrl = file.fileUrl || file.response.data;
  let findIndex = fileSuccess.value.findIndex(item => item.fileUrl == fileUrl);
  if (findIndex != -1) {
    fileSuccess.value.splice(findIndex, 1);
    setMadelVal();
  }
};
const imgView = ref(false);
const urlList = ref([]);
const initialIndex = ref(0);
//预览
const handlePreview = file => {
  let suffix = file.fileUrl.split(".").pop().toLowerCase();
  if (!["jpg", "png", "jpeg"].includes(suffix)) {
    window.open(filePreUrl + file.fileUrl, "_blank");
  } else {
    imgView.value = true;
    initialIndex.value = fileList.value.findIndex(item => {
      return item.url === file.url;
    });
    urlList.value = fileList.value.map(item => {
      return item.url;
    });
  }
};
// 预览图片关闭
function imgViewClose() {
  imgView.value = false;
  urlList.value = [];
}

// 获取显示封面的url
const getShowFileUrl = file => {
  let url = filePreUrl + file.fileUrl;
  if (fileUrlObj[file.suffix]) {
    url = fileUrlObj[file.suffix];
  }
  return url;
};

const getJsonVal = str => {
  // 判断是否是json字符串
  let result = [];
  if (typeof str == "string") {
    try {
      result = JSON.parse(str);
    } catch (e) {
      // console.log('---isJSON_test-err: ', e)
    }
  }
  return result;
};

const setMadelVal = () => {
  let modelval = "";
  if (fileSuccess.value && fileSuccess.value.length > 0) {
    modelval = JSON.stringify(fileSuccess.value);
  }
  emit("update:modelValue", modelval);
};

// 初始化显示
const setFileList = val => {
  fileSuccess.value = getJsonVal(val);
  let tempFileList = fileSuccess.value.map(v => {
    return {
      name: v.name,
      url: getShowFileUrl(v),
      fileUrl: v.fileUrl
    };
  });
  fileList.value = tempFileList;
};

watch(
  () => props.modelValue,
  newValue => {
    if (newValue && !isInit.value) {
      isInit.value = true;
      setFileList(newValue);
    } else if (!newValue) {
      fileList.value = [];
      fileSuccess.value = [];
    }
  },
  { immediate: true }
);
</script>

<style lang="scss" scoped>
.upload .tips {
  color: gray;
}

// 隐藏上传
:deep(.hideAdd .el-upload--picture-card) {
  display: none;
}

:deep(.el-upload--picture-card) {
  width: 100px;
  height: 100px;
}

// 上传进度
:deep(.el-progress-circle) {
  width: 100px !important;
  height: 100px !important;
}

:deep(.el-upload-list--picture-card .el-progress) {
  width: 100% !important;
}

:deep(.el-upload) {
  width: 100px;
  height: 100px;
  line-height: 100px;
}

:deep(.el-upload-list--picture-card .el-upload-list__item) {
  width: 100px;
  height: 100px;
  line-height: 100px;
}

:deep(.el-upload-list--picture-card .el-upload-list__item-thumbnail) {
  width: 80px;
  height: 80px;
  line-height: 80px;
  margin: auto;
}

:deep(.el-upload-list--picture-card .el-upload-list__item-actions) {
  width: 100px;
  height: 100px;
  line-height: 100px;
}

:deep(.avatar) {
  width: 100px;
  height: 100px;
}
</style>
